home *** CD-ROM | disk | FTP | other *** search
/ PC-SIG Library 8 / PC-SIG Library CD-ROM (8th Edition) (1990-04).iso / 201_300 / disk0258 / hc.asm < prev    next >
Encoding:
Assembly Source File  |  1984-05-08  |  41.6 KB  |  1,538 lines

  1. ; hc.asm v1.4           2/10/84
  2. ; fast hexconverter
  3. ; Copyright (C) 1984 Martin Smith
  4. ;
  5. ; Fixes odd line problem, further optimized.
  6. ;
  7. ; Assemble and then use EXE2BIN to make a COM file.
  8. ;
  9. ; Convert com/exe/bin to hex or back.
  10. ; format
  11. ; 1) hc file.hex file.com
  12. ; 2) hc file.com file.hex
  13. ; 3) hc file.hex
  14. ;       program examines file for .exe format, else .com
  15. ; 4) hc file(.com/.exe/.bin)
  16. ;       program outputs file.hex
  17. ; 5) hc
  18. ;       program prints doc.
  19. ; Note: HC does is NOT produce an Intel format HEX file.
  20. ;       Rather it is the modulo 2048 single checksum format
  21. ;       found on many IBM BBS's.
  22.  
  23.         title [[hc]] hexconverter
  24.         page 60,100
  25.  
  26. TRUE    equ     -1
  27. FALSE   equ     0
  28. EOF     equ     26      ; Ctrl-Z
  29. PARAGRAPHS      EQU     256     ; adjust for program size, leaving room
  30.                                 ; for a stack. Generally leave alone.
  31. BUFSIZE         EQU     64      ; for args
  32.  
  33. ; DOS function calls used
  34.  
  35. DISPLAYOUT      EQU     0200H
  36. PRINTSTRING     EQU     0900H
  37. GETDOSVERSION   EQU     3000H
  38. CREAT           EQU     3C00H
  39. OPENFILE        EQU     3D00H
  40. CLOSEFILE       EQU     3E00H
  41. READFILE        EQU     3F00H
  42. WRITEFILE       EQU     4000H
  43. DELETEFILE      EQU     4100H
  44. ALLOCATE        EQU     4800H
  45. FREEMEMORY      EQU     4900H
  46. SETBLOCK        EQU     4A00H
  47.  
  48. cseg    segment para 'code'
  49.         org     100h                    ; COM program
  50.         assume  cs:cseg,ds:cseg
  51.  
  52. start   proc    far
  53.  
  54. begin:
  55.         mov     bp,sp
  56.         mov     cs:oldstack,bp
  57.         test    ax,0ffffh               ; test for invalid drive spec.
  58.         jz      begin_ok
  59.         mov     ax,15                   ; invalid drive
  60.         jmp     report_bad
  61.  
  62. begin_ok:
  63.         mov     ax,cs                   ; better safe than sorry.
  64.         mov     ds,ax
  65.         mov     es,ax
  66.  
  67.         mov     dx,offset himess        ; print greeting
  68.         mov     ax,PRINTSTRING
  69.         int     21h
  70.         mov     si,80h                  ; get args
  71.         mov     di,offset arg1
  72.         mov     cl,[si]
  73.         cmp     cl,0                    ; no args
  74.         jnz     ck_for_right_dos
  75.         jmp     do_doc                  ; so print a documentation
  76.  
  77. ck_for_right_dos:
  78.         push    si
  79.         push    di
  80.         push    cx
  81.         mov     ax,GETDOSVERSION
  82.         int     21h
  83.         pop     cx
  84.         pop     di
  85.         pop     si
  86.         cmp     al,2                    ; dos 2.+ ?
  87.         jnb     dos_ok
  88.         mov     dx,offset must_be_20
  89.         jmp     report_abort
  90.  
  91. dos_ok:
  92.  
  93.         mov     sp,16*PARAGRAPHS-1      ; stack not adjusted by
  94.         mov     bp,sp                   ; SETBLOCK, so must do it here.
  95.                                         ; adjust PARAGRAPHS in EQUates to
  96.                                         ; reflect program size.
  97.         mov     ch,0
  98.  
  99. b2:
  100.         inc     si                      ; ignor leading blanks
  101.         mov     al,[si]
  102.         cmp     al,' '
  103.         jnz     b3
  104.         loop    b2
  105.         jmp     do_doc                  ; do doc if no args
  106.  
  107. b3:
  108.         mov     [di],al                 ; else copy first arg to our space
  109.         inc     di
  110.         inc     si
  111.         mov     al,[si]
  112.         cmp     al,' '
  113.         jz      b4
  114.         cmp     al,13
  115.         jz      b4
  116.         loop    b3
  117.  
  118. b4:
  119.         dec     cx              ; got an arg, allow for trailing blanks
  120.         mov     al,0            ; keep up with CX to use LOOP instruction
  121.         mov     [di],al
  122.         mov     byte ptr cs:numargs,1
  123.         cmp     cx,0
  124.         jnz     b5
  125.         jmp     memory_setup
  126.  
  127. b5:
  128.         mov     di,offset arg2  ; after this its arg2
  129.         dec     cx              ; keep up with CX
  130.         cmp     cx,0
  131.         jnz     b6
  132.         jmp     memory_setup
  133.  
  134. b6:
  135.         inc     si              ; ignor leading blanks
  136.         mov     al,[si]
  137.         cmp     al,' '
  138.         jnz     b7
  139.         loop    b6
  140.         jmp     memory_setup    ; go to next if nothing
  141.  
  142. b7:
  143.         mov     [di],al         ; else copy input to our space.
  144.         inc     di
  145.         inc     si
  146.         mov     al,[si]
  147.         cmp     al,' '
  148.         jz      b8
  149.         cmp     al,13
  150.         jz      b8
  151.         loop    b7
  152.  
  153. b8:
  154.         mov     al,0            ; got an arg, put \0 for ASCIZ
  155.         mov     [di],al
  156.         mov     byte ptr cs:numargs,2
  157.         jmp     memory_setup    ; ignor any more
  158.  
  159. start   endp
  160.  
  161. do_doc  proc    near
  162.  
  163.         mov     dx,offset doc   ; print until $
  164.         mov     ax,PRINTSTRING
  165.         int     21h
  166.         mov     dx,offset do_cr
  167.         jmp     report_abort    ; exit
  168.  
  169. do_doc  endp
  170.  
  171. report_bad      proc    near
  172. ;
  173. ; use AX error return to point DX to message from
  174. ; error return table
  175. ;
  176.         push    cs
  177.         pop     ds
  178.         shl     ax,1
  179.         mov     si,offset error
  180.         add     si,ax
  181.         mov     dx,[si]
  182.  
  183. report_bad      endp
  184.  
  185. report_abort    proc    near
  186. ;
  187. ; print message from DX, restore regs and abort.
  188. ; common exit, neatness counts.
  189. ; plus we've screwed around with the stack.
  190. ;
  191.         assume  ds:cseg
  192.  
  193.         mov     bp,cs:oldstack
  194.         mov     sp,bp
  195.         mov     ax,cs
  196.         mov     ds,ax
  197.         mov     es,ax
  198.         mov     ax,PRINTSTRING
  199.         int     21h
  200.         int     20h                     ; common exit all routines
  201.  
  202. report_abort    endp
  203.  
  204. hexbin  proc    near
  205. ;
  206. ;       Convert HEX to binary
  207. ;
  208. ; Call with     DL = first HEX digit
  209. ;               DH = second HEX digit
  210. ;
  211. ; Returns with  DL = converted byte
  212. ;               Carry flag = 0  valid input
  213. ;               Carry flag = 1  invalid input
  214. ;               Other registers preserved.
  215. ;
  216. ;       From Dr. Dobbs #74
  217. ;       December 1982  p.14
  218. ;       by Robert Blair
  219. ;
  220.         push    cx
  221.         push    bx
  222.         mov     bl,dl
  223.         call    hexbin_test
  224.         mov     bh,bl
  225.         mov     bl,dh
  226.         call    hexbin_test
  227.         mov     cx,4
  228.         shl     bh,cl
  229.         and     bl,00001111b
  230.         mov     dl,bh
  231.         or      dl,bl
  232.         clc
  233.         pop     bx
  234.         pop     cx
  235.         ret
  236. hexbin_test:
  237.         cmp     bl,'0'
  238.         jb      hexbin_error
  239.         cmp     bl,'9'
  240.         ja      $+3
  241.         ret
  242. ;       cmp     bl,'f'          ; don't swap capitols here
  243. ;       ja      hexbin_error
  244. ;       cmp     bl,'a'          ; lowercase is allright after all.
  245. ;       jb      $+6
  246. ;       add     bl,9            ; uncomment this if they start up with
  247. ;       ret                     ; lowercase hex files.
  248.         cmp     bl,'A'
  249.         jb      hexbin_error
  250.         cmp     bl,'F'
  251.         ja      hexbin_error
  252.         add     bl,9
  253.         ret
  254. hexbin_error:
  255.         clc
  256.         cmc
  257.         pop     bx
  258.         pop     bx
  259.         pop     cx
  260.         ret
  261. hexbin  endp
  262.  
  263. binhex  proc    near
  264. ;
  265. ; Convert binary to hex
  266. ;
  267. ; Call with     DL = byte to convert
  268. ;
  269. ; Returns with  DL = first HEX digit
  270. ;               DH = second HEX digit
  271. ;               Other registers preserved
  272. ;
  273.         push    cx
  274.         push    bx
  275.         mov     cx,4
  276.         mov     dh,dl
  277.         shr     dl,cl
  278.         and     dh,00001111b
  279.         sub     bh,bh
  280.         mov     bl,dl
  281.         mov     dl,cs:translate_hex [bx]
  282.         mov     bl,dh
  283.         mov     dh,cs:translate_hex [bx]
  284.         pop     bx
  285.         pop     cx
  286.         ret
  287.  
  288. translate_hex   db      '0123456789ABCDEF'
  289.  
  290. binhex  endp
  291.  
  292.  
  293. print   proc    near
  294. ;
  295. ; print string until \0
  296. ; SI points to first character
  297. ; All other regs preserved
  298. ; String in CS
  299. ;
  300.         push    ds
  301.         push    ax
  302.         push    dx
  303.         mov     ax,cs
  304.         mov     ds,ax
  305.  
  306. pr1:
  307.         mov     dl,[si]
  308.         cmp     dl,0
  309.         jz      pr2
  310.         mov     ax,DISPLAYOUT
  311.         int     21h
  312.         inc     si
  313.         jmp     pr1
  314.  
  315. pr2:
  316.         mov     dl,' '                  ; insert space for neatness.
  317.         mov     ax,DISPLAYOUT
  318.         int     21h
  319.         pop     dx
  320.         pop     ax
  321.         pop     ds
  322.         ret
  323.  
  324. print   endp
  325.  
  326. crlf    proc    near
  327.                                 ; send a carriage return/line feed
  328.         push    dx              ; to console.
  329.         push    ax
  330.         mov     ax,DISPLAYOUT
  331.         mov     dl,13
  332.         int     21h
  333.         mov     ax,DISPLAYOUT
  334.         mov     dl,10
  335.         int     21h
  336.         pop     ax
  337.         pop     dx
  338.         ret
  339.  
  340. crlf    endp
  341.  
  342. free_memory     proc    near
  343.  
  344.         push    ax              ; gives back memory we allocated,
  345.         mov     ax,cs:comseg    ; preserves AX, which maybe has
  346.         mov     es,ax           ; error code.
  347.         mov     ax,FREEMEMORY
  348.         int     21h
  349.         jc      fm_bad
  350.         mov     ax,cs:txtseg
  351.         mov     es,ax
  352.         mov     ax,FREEMEMORY
  353.         int     21h
  354.         jc      fm_bad
  355.         pop     ax
  356.         ret
  357.  
  358. fm_bad:
  359.         jmp     report_bad
  360.  
  361. free_memory     endp
  362.  
  363.  
  364. memory_setup    proc    near
  365. ;
  366. ;       request 96k, adjust for less
  367. ;
  368.         assume  ds:nothing
  369.         mov     bx,PARAGRAPHS           ; adjust to actual. Use equ at top
  370.         mov     ax,SETBLOCK
  371.         int     21h                     ; SETBLOCK - shrink us
  372.         jnc     msa
  373.         jmp     report_bad
  374.  
  375. msa:
  376.         mov     bx,1800h                ; ask for 96k
  377.         mov     ax,ALLOCATE
  378.         int     21h
  379.         jnc     msb
  380.         cmp     ax,8                    ; insufficient memory
  381.         jz      ms1
  382.  
  383. msb:
  384.         mov     bx,1800h                ; got our request
  385.         jmp     ms2
  386.  
  387. ms1:
  388.         push    bx
  389.         mov     ax,ALLOCATE
  390.         int     21h                     ; so ask for less
  391.         jnc     msc
  392.         jmp     report_bad              ; still fouled up?
  393.  
  394. msc:
  395.         pop     bx
  396.  
  397. ms2:
  398.         mov     cs:txtseg,ax
  399.         mov     es,ax                   ; now have allocated total space
  400.         mov     dx,0
  401.         mov     ax,bx
  402.         mov     cx,3
  403.         div     cx                      ; divide by three
  404.         dec     ax                      ; safety factor
  405.         mov     cs:space,ax
  406.         mov     bx,ax
  407.         shl     bx,1                    ; multiply by 2
  408.         mov     ax,SETBLOCK             ; shrink our total space
  409.         int     21h
  410.         jnc     ms2a
  411.         jmp     report_bad              ; get out if error after all this
  412.  
  413. ms2a:
  414.         mov     bx,cs:space
  415.         mov     ax,ALLOCATE             ; allocate second block
  416.         int     21h
  417.         jnc     ms3
  418.         jmp     report_bad
  419.  
  420. ms3:
  421.         mov     cs:comseg,ax
  422.         mov     bx,cs:space             ; get 1/3 of paragraphs
  423.         mov     cl,4
  424.         shl     bx,cl                   ; times 16 = bytes available
  425.         dec     bx                      ; sub 2 for safety
  426.         dec     bx
  427.         mov     cs:comspace,bx          ; com file put here in either
  428.         inc     bx                      ; routine.
  429.         inc     bx
  430.         shl     bx,1                    ; times 2 = text space
  431.         dec     bx
  432.         dec     bx
  433.         mov     cs:txtspace,bx          ; hex file always in this one.
  434.         mov     ax,cs:txtspace          ; [bp-2]  structure for easy access
  435.                                         ;         to end of space.
  436.         push    ax                      ;         Valid in either routine.
  437.         mov     ax,cs:comspace          ; [bp-4]
  438.         push    ax
  439.         mov     ax,cs                   ; don't use blocks yet, have
  440.         mov     ds,ax                   ; to do file setup.
  441.         mov     es,ax
  442.         jmp     open_files
  443.  
  444. memory_setup    endp
  445.  
  446. write_hc        proc    near
  447.         assume  ds:nothing              ; universal write to file routine.
  448.         push    cx                      ; Saves registers used in time
  449.         push    bx                      ; critical loops, provides safe
  450.         push    ds                      ; error exits. Most of the errors
  451.         push    es                      ; in this program will come from
  452.         pop     ds                      ; disk, so take care here.
  453.         mov     dx,0
  454.         mov     cx,di
  455.         mov     bx,cs:handle2           ; assume file already open for write
  456.         mov     ax,WRITEFILE
  457.         int     21h
  458.         jnc     whc1
  459.         push    cs
  460.         pop     ds
  461.         mov     si,offset arg2          ; lots of messages for foul ups
  462.         call    print
  463.         call    crlf
  464.         shl     ax,1
  465.         mov     si,offset error
  466.         add     si,ax
  467.         mov     dx,[si]
  468.         mov     ax,PRINTSTRING
  469.         int     21h
  470.         jmp     bad_input               ; bad_input tidies up mess.
  471.  
  472. whc1:
  473.         cmp     di,ax
  474.         jnz     wh_full
  475.         mov     ax,0
  476.         add     cs:f_size,di
  477.         adc     cs:f_size+2,ax
  478.         mov     di,0
  479.         pop     ds
  480.         pop     bx
  481.         pop     cx
  482.         ret
  483.  
  484. wh_full:
  485.         mov     si,offset cs:disk_full  ; if disk is full,
  486.         call    print
  487.         call    crlf
  488.         call    free_memory
  489.         mov     bx,cs:handle2
  490.         mov     ax,CLOSEFILE            ; close file,
  491.         int     21h
  492.         jnc     wh_full2
  493.         jmp     report_bad
  494.  
  495. wh_full2:
  496.         push    cs
  497.         pop     ds
  498.         mov     dx,offset arg2
  499.         mov     ax,DELETEFILE           ; then delete it from disk.
  500.         int     21h                     ; save user some time.
  501.         jnc     wh_full3
  502.         jmp     report_bad
  503.  
  504. wh_full3:
  505.         mov     dx,offset cs:cancelled
  506.         jmp     report_abort
  507.  
  508. write_hc        endp
  509.  
  510. hcread  proc    near
  511.                                         ; universal read from file routine.
  512.         push    bx                      ; just slight differences for
  513.         mov     cx,cs:txtspace          ; com->hex and hex<-com.
  514.         push    cx
  515.         jmp     read_input
  516.  
  517. hcread  endp
  518.  
  519. chread  proc    near
  520.  
  521.         push    bx
  522.         mov     cx,cs:comspace
  523.         push    cx
  524.         jmp     read_input
  525.  
  526. chread  endp
  527.  
  528. read_input      proc    near
  529.  
  530.         mov     bx,cs:handle1
  531.         mov     dx,0
  532.         mov     ax,READFILE
  533.         int     21h                     ; read from file
  534.         jnc     ri_ok
  535.         push    ax                      ; if we come back with the
  536.         push    cs                      ; carry flag set, things didn't
  537.         pop     ds                      ; go allright, so we had better
  538.         mov     si,offset arg1          ; not continue
  539.         call    print
  540.         call    crlf
  541.         mov     bx,cs:handle2
  542.         mov     ax,CLOSEFILE            ; close 2
  543.         int     21h
  544.         call    free_memory
  545.         mov     dx,offset arg2
  546.         mov     ax,DELETEFILE           ; delete
  547.         int     21h
  548.         mov     dx,offset cs:cancelled
  549.         mov     ax,PRINTSTRING
  550.         int     21h
  551.         pop     ax
  552.         jmp     report_bad
  553.  
  554. ri_ok:
  555.  
  556.         cmp     ax,0                    ; EOF and no checksum?
  557.         jnz     ri1                     ; special case for HEX file.
  558.         cmp     byte ptr cs:com_to_hex,TRUE   ; its all right to not have
  559.         jz      ri1                     ; a checksum, but theres no
  560.         jmp     no_hc_checksum          ; sense in heading back to
  561.                                         ; the process loop.
  562. ri1:
  563.         mov     si,ax
  564.         mov     byte ptr [si],0ffh      ; set last byte to ff for check
  565.         pop     cx
  566.         pop     bx
  567.         mov     si,0
  568.         cmp     ax,cx                   ; all read in?
  569.         jb      ri_done
  570.  
  571.         ret
  572.  
  573. ri_done:
  574.         mov     byte ptr cs:all_read,TRUE  ; set flag indicating no more
  575.         cmp     byte ptr cs:com_to_hex,TRUE  ; reading required
  576.         jnz     ri_hc
  577.         mov     cs:comspace,ax          ; store maxbytes all over
  578.         mov     [bp-4],ax
  579.         mov     cx,ax
  580.         ret
  581.  
  582. ri_hc:
  583.         mov     cs:txtspace,ax
  584.         mov     [bp-2],ax
  585.         mov     cx,ax
  586.         ret
  587.  
  588. read_input      endp
  589.  
  590.  
  591. open_files      proc    near
  592.  
  593.  
  594.         mov     ax,cs
  595.         mov     ds,ax
  596.         mov     cx,BUFSIZE*2            ; make args lowercase
  597.         mov     si,offset arg1
  598.  
  599. of2:
  600.         mov     al,[si]
  601.         cmp     al,'A'
  602.         jl      of3
  603.         cmp     al,'Z'
  604.         ja      of3
  605.         add     al,32
  606.         mov     [si],al
  607.  
  608. of3:
  609.         inc     si
  610.         loop    of2
  611.  
  612.         cmp     byte ptr cs:numargs,2      ; have to find which is hex
  613.         jz      of4
  614.         jmp     find_files
  615.  
  616. of4:
  617.         mov     si,offset arg1
  618.  
  619. of4a:
  620.  
  621.         mov     al,[si]
  622.         cmp     al,'.'
  623.         jz      of5
  624.         inc     si
  625.         cmp     al,0            ; end of arg and no extension
  626.         jnz     of4a
  627.         mov     byte ptr cs:com_to_hex,TRUE ; better be true
  628.         jmp     of10
  629.  
  630. of5:
  631.         inc     si
  632.         mov     al,[si]
  633.         cmp     al,'h'          ; is this hex?
  634.         jz      of6
  635.         mov     byte ptr cs:com_to_hex,TRUE ; set flag
  636.         jmp     of10
  637.  
  638. of6:
  639.         mov     byte ptr cs:com_to_hex,FALSE  ; first arg is HEX,
  640.         jmp     open                          ; so its hex_to_com.
  641.  
  642. of10:
  643.         mov     si,offset arg2
  644.  
  645. of11:
  646.         mov     al,[si]
  647.         cmp     al,'.'          ; look for .
  648.         jz      of12
  649.         inc     si
  650.         cmp     al,0            ; end of arg and no extension
  651.         jnz     of11
  652.         call    free_memory
  653.         mov     dx,offset need_hex   ; two args, one has to be hex
  654.         jmp     report_abort
  655.  
  656. of12:
  657.         inc     si
  658.         mov     al,[si]
  659.         cmp     al,'h'          ; here this better be HEX
  660.         jz      of13
  661.         call    free_memory     ; otherwise bye bye
  662.         mov     dx,offset need_hex
  663.         jmp     report_abort
  664.  
  665. of13:
  666.         jmp     open
  667.  
  668. find_files:                     ; only one arg supplied, have to find which
  669.         mov     si,offset arg1
  670.         mov     di,offset arg2
  671.  
  672. ff1:
  673.         mov     al,[si]         ; search for extension
  674.         mov     [di],al
  675.         cmp     al,'.'
  676.         jz      ff2
  677.         inc     si
  678.         inc     di
  679.         cmp     al,0            ; no ext means com_to_hex
  680.         jnz     ff1
  681.  
  682.         dec     di
  683.  
  684.         mov     byte ptr cs:com_to_hex,TRUE ; make second arg HEX
  685.         mov     al,'.'
  686.         mov     [di],al
  687.  
  688. ff1a:
  689.         mov     al,'h'
  690.         inc     di
  691.         mov     [di],al
  692.         mov     al,'e'
  693.         inc     di
  694.         mov     [di],al
  695.         mov     al,'x'
  696.         inc     di
  697.         mov     [di],al
  698.         mov     al,0
  699.         inc     di
  700.         mov     [di],al
  701.         jmp     open
  702.  
  703. ff2:
  704.         inc     si
  705.         inc     di
  706.         mov     cs:temp,di
  707.         mov     al,[si]
  708.         cmp     al,'h'          ; is it hex?
  709.         jz      ff3
  710.  
  711.         mov     byte ptr cs:check_exe,FALSE ; no, make second HEX
  712.         mov     byte ptr cs:com_to_hex,TRUE
  713.         dec     di
  714.         jmp     ff1a
  715.  
  716. ff3:
  717.         mov     byte ptr cs:check_exe,TRUE
  718.         mov     byte ptr cs:com_to_hex,FALSE
  719.  
  720. open:           ; we now have 2 args, with one possibly waiting
  721.                 ; for COM or EXE extension
  722.         assume  ds:cseg
  723.         mov     ax,cs
  724.         mov     ds,ax
  725.         cmp     byte ptr cs:com_to_hex,TRUE
  726.         jz      openc
  727.         jmp     openh
  728.  
  729. openc:
  730.         mov     dx,offset arg1
  731.         mov     ax,OPENFILE     ; for reading
  732.         clc
  733.         int     21h
  734.         jnc     opcok
  735.         mov     si,offset arg1
  736.         call    print
  737.         call    free_memory
  738.         jmp     report_bad
  739.  
  740. opcok:
  741.         mov     cs:handle1,ax
  742.  
  743.         mov     dx,offset arg2
  744.         mov     cx,0            ; normal file attribute
  745.         mov     ax,CREAT
  746.         clc
  747.         int     21h
  748.         jnc     opcok1
  749.         mov     si,offset arg2  ; print which file caused error
  750.         call    print
  751.         call    free_memory
  752.         jmp     report_bad
  753.  
  754. opcok1:
  755.         mov     cs:handle2,ax   ; otherwise store handle
  756.         jmp     com_hex         ; do com->hex
  757.  
  758. openh:
  759.         mov     dx,offset arg1
  760.         mov     ax,OPENFILE     ; for reading
  761.         clc
  762.         int     21h
  763.         jnc     ophok
  764.         mov     si,offset arg1
  765.         call    print
  766.         jmp     report_bad
  767.  
  768. ophok:
  769.         mov     cs:handle1,ax
  770.         cmp     byte ptr cs:check_exe,TRUE
  771.         jz      opcheck
  772.         jmp     ophok1
  773.  
  774. opcheck:
  775.         assume  ds:nothing      ; here we read in first block
  776.         mov     ax,cs:txtseg    ; then look for the  MZ
  777.         mov     ds,ax           ; footprint of an EXE file.
  778.  
  779.         call    hcread
  780.  
  781. opcheck2:
  782.         mov     si,0
  783.  
  784. opchl:
  785.         mov     dl,[si]         ; ignor all leading stuff until
  786.         cmp     dl,13           ; first convertible bytes
  787.         jz      opch1
  788.         cmp     dl,10
  789.         jz      opch1
  790.         cmp     dl,' '
  791.         jz      opch1
  792.         cmp     dl,';'
  793.         jnz     opch4
  794.         call    op_find
  795.  
  796.         jmp     opchl
  797.  
  798. opch1:
  799.         inc     si
  800.         jmp     opchl
  801.  
  802. opch4:
  803.  
  804.         inc     si
  805.         mov     dh,[si]
  806.         call    hexbin          ; hexbin comes back with carry set
  807.         jnc     opch5           ; if it can't convert input.
  808.         jmp     opcom           ; can't make sense, so make com
  809.  
  810. opch5:
  811.         mov     al,dl
  812.         inc     si
  813.         mov     dx,[si]
  814.         call    hexbin
  815.         jnc     opch6
  816.         jmp     opcom
  817.  
  818. opch6:
  819.         mov     dh,dl
  820.         mov     dl,al
  821.         push    cs
  822.         pop     ds
  823.         cmp     dx,5a4dh        ; MZ are the first two bytes of an EXE file.
  824.         jz      opexe           ; make ext EXE
  825.         jmp     opcom           ; make ext COM
  826.  
  827. op_find:
  828.         inc     si              ; simple ignor
  829.         mov     dl,[si]         ; we can convert files downloaded
  830.         cmp     dl,13           ; without line feeds.
  831.         jnz     op_find
  832.         inc     si
  833.         mov     dl,[si]
  834.         cmp     dl,10
  835.         jnz     opf1
  836.         inc     si
  837.  
  838. opf1:
  839.         ret
  840.  
  841. opexe:
  842.         mov     si,cs:temp
  843.         mov     al,'e'
  844.         mov     [si],al
  845.         inc     si
  846.         mov     al,'x'
  847.         mov     [si],al
  848.         inc     si
  849.         mov     al,'e'
  850.         mov     [si],al
  851.         inc     si
  852.         mov     al,0
  853.         mov     [si],al
  854.         jmp     ophok1
  855.  
  856. opcom:
  857.         mov     si,cs:temp
  858.         mov     al,'c'
  859.         mov     [si],al
  860.         inc     si
  861.         mov     al,'o'
  862.         mov     [si],al
  863.         inc     si
  864.         mov     al,'m'
  865.         mov     [si],al
  866.         inc     si
  867.         mov     al,0
  868.         mov     [si],al
  869.  
  870. ophok1:
  871. ; now have second arg for sure
  872.         mov     dx,offset arg2
  873.         mov     cx,0
  874.         mov     ax,CREAT        ; CREATE a file
  875.         clc
  876.         int     21h
  877.         jnc     ophok2
  878.         mov     si,offset arg2
  879.         call    print
  880.         call    free_memory
  881.         jmp     report_bad
  882.  
  883. ophok2:
  884.         mov     cs:handle2,ax
  885.  
  886. open_files      endp
  887.  
  888. hex_com         proc    near
  889.  
  890.         mov     ax,cs:txtseg    ; finally use our memory set-up
  891.         mov     ds,ax
  892.         mov     ax,cs:comseg    ; DS always input, ES always output
  893.         mov     es,ax
  894.                                 ; first check if data already in buffer
  895.  
  896.         mov     al,byte ptr cs:check_exe
  897.         cmp     al,TRUE
  898.         jnz     hc1
  899.         jmp     hc_read
  900.  
  901. hc1:
  902.         call    hcread
  903.  
  904. hc_read:
  905.         mov     si,0
  906.         mov     di,0
  907.         mov     bx,0            ; checksum stored in BX, don't lose it
  908.         mov     cx,cs:txtspace
  909.  
  910. hcloop:
  911.         mov     dl,[si]         ; most used routine, process stuff till
  912.         cmp     dl,13           ; out of space in buffer or EOF
  913.         jz      hclcont
  914.         cmp     dl,10
  915.         jz      hclcont
  916.         cmp     dl,' '
  917.         jz      hclcont
  918.         cmp     dl,';'
  919.         jz      hcl8
  920.  
  921. hcl1:
  922.         cmp     dl,0ffh         ; if we run out of data,
  923.         jz      hcl6
  924.  
  925. hcl2:
  926.         inc     si
  927.  
  928. hcl3:
  929.         mov     dh,[si]
  930.         cmp     dh,0ffh
  931.         jz      hcl5
  932.         call    hexbin          ; if nothing else works it must be data
  933.         jc      bad_i
  934.  
  935. hcl4:
  936.         mov     es:[di],dl      ; store
  937.         xor     dh,dh
  938.         add     bx,dx           ; checksum
  939.         and     bx,07ffh
  940.         inc     di
  941.         cmp     di,[bp-4]       ; output buffer size in [bp-4]
  942.         jz      hcl7
  943.  
  944. hclcont:
  945.         inc     si
  946.  
  947.         jmp     hcloop
  948.  
  949. hcl5:
  950.         push    dx
  951.         call    hcread          ; if we fall through here, we need more
  952.         pop     dx
  953.         jmp     hcl3            ; data, then go back for more loop.
  954.  
  955. hcl6:
  956.         call    hcread          ; go dig up some more.
  957.         jmp     hcloop
  958.  
  959. hcl7:
  960.         call    write_hc        ; write buffer when full.
  961.         jmp     hclcont
  962.  
  963. hcl8:
  964.         sub     cx,si           ; checksum uses cx
  965.         call    checksum        ; may or may not return to here
  966.         jmp     hclcont
  967. bad_i:
  968.         push    cs
  969.         pop     ds
  970.         mov     si,offset arg1
  971.         call    print              ; if hexbin comes back invalid
  972.         call    crlf               ; abort routine and clean up.
  973.         mov     dx,offset not_hex
  974.         mov     ax,PRINTSTRING
  975.         int     21h
  976.  
  977. bad_input:
  978.         call    free_memory     ; restores memory to original,
  979.         mov     bx,cs:handle1   ; closes both files,
  980.         mov     ax,CLOSEFILE    ; then deletes output file.
  981.         int     21h
  982.         jnc     bi1
  983.         jmp     report_bad
  984.  
  985. bi1:
  986.         mov     bx,cs:handle2
  987.         mov     ax,CLOSEFILE
  988.         int     21h
  989.         jnc     bi2
  990.         jmp     report_bad
  991.  
  992. bi2:
  993.         push    cs
  994.         pop     ds
  995.         mov     dx,offset cs:arg2
  996.         mov     ax,DELETEFILE
  997.         int     21h             ; delete output file
  998.         jnc     bi3
  999.         jmp     report_bad
  1000.  
  1001. bi3:
  1002.         mov     dx,offset cs:cancelled
  1003.         jmp     report_abort
  1004.  
  1005.  
  1006. hex_com endp
  1007.  
  1008. checksum        proc    near
  1009. ;
  1010. ; si points to ';'
  1011. ; check for checksum, else read to end of line
  1012. ;
  1013.         push    es
  1014.         push    di
  1015.         mov     ax,cs
  1016.         mov     es,ax
  1017.         cld
  1018.         mov     dh,0
  1019.         inc     si
  1020.         cmp     dl,0ffh         ; its possible to hit end of buffer
  1021.         jnz     ch0             ; during this, so we need to check
  1022.         call    hcread          ; and cope.
  1023.  
  1024. ch0:
  1025.         mov     dl,[si]         ; we can convert ;checksum
  1026.         cmp     dl,'c'          ;             or ;CHECKSUM
  1027.         jnz     ch0a
  1028.         mov     di,offset cs:lchksum+1
  1029.         jmp     ch1
  1030.  
  1031. ch0a:
  1032.         cmp     dl,'C'
  1033.         jnz     ch_read_end
  1034.         mov     di,offset cs:uchksum+1
  1035.  
  1036. ch1:
  1037.         cmpsb                   ; compare till the bitter end.
  1038.         jnz     ch_read_end
  1039.         dec     cx
  1040.         cmp     cx,0
  1041.         jnz     ch2
  1042.         call    hcread
  1043.  
  1044. ch2:
  1045.         inc     dh
  1046.         cmp     dh,8
  1047.         jnz     ch1
  1048.         pop     di
  1049.         pop     es              ; this is it.
  1050.         pop     ax              ; discard return, no longer need hcloop
  1051.         jmp     dhc1            ; found checksum word
  1052.  
  1053. ch_read_end:
  1054.         dec     si
  1055.  
  1056. cre1:
  1057.         mov     dl,[si]         ; no find, so read till end
  1058.         cmp     dl,13           ; of line and go back to hcloop
  1059.         jz      cre_back
  1060.         inc     si
  1061.         dec     cx
  1062.         cmp     cx,0
  1063.         jnz     cre2
  1064.         call    hcread
  1065.  
  1066. cre2:
  1067.         jmp     cre1
  1068.  
  1069. cre_back:
  1070.         pop     di
  1071.         pop     es
  1072.         ret
  1073.  
  1074. dhc1:
  1075.         mov     dl,[si]         ; ignor leading blanks
  1076.         cmp     dl,' '
  1077.         jnz     dhc2
  1078.         inc     si
  1079.         dec     cx
  1080.         cmp     cx,0
  1081.         jnz     dhc1
  1082.         call    hcread          ; get more text if end of buffer
  1083.         jmp     dhc1
  1084.  
  1085. dhc2:
  1086.         push    cx              ; convert ASCII checksum to binary
  1087.         mov     ax,0
  1088.         mov     cx,10
  1089.         mov     dh,0
  1090.  
  1091. dhc3:
  1092.         mov     dl,[si]         ; read numbers until no number
  1093.         cmp     dl,'0'
  1094.         jae     dhc4
  1095.         jmp     dhc_found
  1096.  
  1097. dhc4:
  1098.         cmp     dl,'9'
  1099.         jbe     dhc5
  1100.         jmp     dhc_found
  1101.  
  1102. dhc5:
  1103.         push    dx              ; the old multiply by ten routine
  1104.         mov     dx,0            ; to convert ASCII number string
  1105.         mul     cx              ; into binary
  1106.         pop     dx
  1107.         sub     dl,'0'
  1108.         add     ax,dx
  1109.         inc     si
  1110.         pop     cx
  1111.         dec     cx              ; CX still has the loop or buffer count
  1112.         cmp     cx,0
  1113.         jnz     dhc5a
  1114.         call    hcread          ; oops, ran out of buffer, so fill up again.
  1115.  
  1116. dhc5a:
  1117.         push    cx
  1118.         mov     cx,10
  1119.         jmp     dhc3
  1120.  
  1121. dhc_found:
  1122.         pop     cx              ; got a checksum.
  1123.         cmp     bx,ax           ; does checksum check out?
  1124.         jz      dhc_ok
  1125.         mov     si,offset cs:chk_bad
  1126.         call    print
  1127.         call    crlf
  1128.         jmp     dhc_cont        ; report either way.
  1129.  
  1130. dhc_ok:
  1131.         mov     si,offset cs:chk_ok
  1132.         call    print
  1133.         call    crlf
  1134.         jmp     dhc_cont
  1135.  
  1136. no_hc_checksum:
  1137.         mov     si,offset chk_no  ; its OK not to have a checksum,
  1138.         call    print           ; but we're more confident if its there
  1139.         call    crlf
  1140.  
  1141. dhc_cont:
  1142.         call    write_hc        ; write final section.
  1143.  
  1144. dhcok1:
  1145.         mov     bx,cs:handle2
  1146.         mov     ax,CLOSEFILE
  1147.         int     21h             ; close outfile
  1148.         jnc     dhcok2
  1149.         call    free_memory     ; hope things don't bomb after all this
  1150.         jmp     report_bad
  1151.  
  1152. dhcok2:
  1153.         mov     bx,cs:handle1
  1154.         mov     ax,CLOSEFILE
  1155.         int     21h             ; close infile
  1156.         jnc     dhcok3
  1157.         call    free_memory
  1158.         jmp     report_bad
  1159.  
  1160. dhcok3:
  1161.  
  1162.         call    free_memory     ; give back memory
  1163.         mov     si,offset cs:arg2
  1164.         call    print
  1165.         call    crlf
  1166.         call    print_file_size
  1167.         mov     dx,offset cs:msuccess  ; print a reassuring message
  1168.         jmp     report_abort    ; clean up and go home.
  1169.  
  1170. checksum  endp
  1171.  
  1172. print_file_size proc    near
  1173.                                 ; print out file size bytes using
  1174.         assume  ds:cseg         ; bcd table
  1175.         push    cs
  1176.         pop     ds
  1177.         mov     bx,offset cs:bcd0
  1178.         mov     si,0
  1179.         mov     ax,cs:f_size
  1180.         mov     dx,1
  1181.  
  1182. pfs1:
  1183.         test    ax,dx           ; test bits
  1184.         jz      pfs2
  1185.         call    add_bcd         ; add in bcd if so
  1186.  
  1187. pfs2:
  1188.         add     si,5            ; bump pointer
  1189.         cmp     dx,8000h        ; test for end
  1190.         jz      pfs3
  1191.         shl     dx,1            ; get next test
  1192.         jmp     pfs1
  1193.  
  1194. pfs3:
  1195.         mov     ax,cs:f_size+2  ; get hi word
  1196.         mov     dx,1            ; start again
  1197.  
  1198. pfs4:
  1199.         test    ax,dx
  1200.         jz      pfs5
  1201.         call    add_bcd
  1202.  
  1203. pfs5:
  1204.         add     si,5
  1205.         cmp     dx,0100h        ; only need up to 16meg
  1206.         jz      pfs6
  1207.         shl     dx,1
  1208.         jmp     pfs4
  1209.  
  1210. pfs6:
  1211.         mov     si,offset bf_size
  1212.         call    print_bcd       ; print out result
  1213.         mov     si,offset cs:f_len
  1214.         call    print           ; print 'bytes recorded'
  1215.         call    crlf
  1216.         ret                     ; back
  1217.  
  1218. add_bcd:
  1219.         push    si
  1220.         push    ax
  1221.         mov     di,offset bf_size  ; point to bcd storage
  1222.         mov     cx,5            ; its five bytes long
  1223.         clc                     ; clear carry to start
  1224.  
  1225. ab1:
  1226.         mov     al,[bx+si]      ; get byte
  1227.         adc     al,[di]         ; add
  1228.         daa                     ; adjust for bcd
  1229.         mov     [di],al         ; store
  1230.         inc     si              ; bump
  1231.         inc     di
  1232.         dec     cx              ; check
  1233.         jnz     ab1             ; leave if done
  1234.  
  1235.         pop     ax
  1236.         pop     si
  1237.         ret
  1238.  
  1239. print_bcd:
  1240.         add     si,4            ; go to end (high byte)
  1241.         mov     cx,5            ; set up for five total
  1242.         mov     ax,0            ; AH used to check first zero
  1243.  
  1244. pbd1:
  1245.         mov     dl,[si]         ; get byte
  1246.         cmp     ah,1            ; see if we've started to print
  1247.         jz      pbd2            ; if so don't skip
  1248.         cmp     dl,0            ; else check if zero
  1249.         jz      pbd3            ; and skip if so
  1250.  
  1251. pbd2:
  1252.         mov     dh,dl           ; copy
  1253.         push    cx              ; don't lose place
  1254.         push    ax
  1255.         mov     cl,4            ; bcd:( 12 hex. = 12 dec. for example)
  1256.         shr     dl,cl           ; shr makes ( 01 )
  1257.         cmp     ah,1            ; if printing print
  1258.         jz      pbd2a
  1259.         cmp     dl,0            ; else see if zero
  1260.         jz      pbd2c           ; and don't print if so
  1261.  
  1262. pbd2a:
  1263.         add     dl,30h          ; make ASCII ( '1' )
  1264.         push    dx
  1265.         mov     ax,DISPLAYOUT   ; print
  1266.         int     21h
  1267.         pop     dx
  1268.  
  1269. pbd2c:
  1270.         mov     dl,dh           ; get copy ( 12 )
  1271.         and     dl,0fh          ; mask     ( 02 )
  1272.         add     dl,30h          ; make ASCII ( '2' )
  1273.         mov     ax,DISPLAYOUT   ; print
  1274.         int     21h
  1275.         pop     ax
  1276.         pop     cx
  1277.         mov     ah,1            ; now set flag to print rest
  1278.  
  1279. pbd3:
  1280.         dec     si
  1281.         dec     cx
  1282.         jnz     pbd1            ; loop till done.
  1283.         ret
  1284.  
  1285. print_file_size endp
  1286.  
  1287.  
  1288. com_hex         proc    near
  1289. ; files are open, nothing read in yet.
  1290.  
  1291.         mov     ax,cs:txtseg    ; do everything in reverse
  1292.         mov     es,ax
  1293.         mov     ax,cs:comseg    ; remember in-buffer = DS
  1294.         mov     ds,ax           ;         out-buffer = ES
  1295.         mov     si,0
  1296.         mov     di,0
  1297.         mov     bx,0
  1298.  
  1299.         call    chread
  1300.         mov     ah,0            ; use for line length
  1301.                                 ; need to put crlf every 32(64) bytes.
  1302. chloop:
  1303.         mov     dl,[si]         ; this is much simpler than hex->com
  1304.         mov     dh,0            ; because there is no extraneous stuff
  1305.         add     bx,dx           ; chloop is time-critical, cause
  1306.         and     bx,07ffh        ; its 90% of routine
  1307.         call    binhex
  1308.         mov     es:[di],dx
  1309.         inc     ah
  1310.         cmp     ah,32
  1311.         jnz     ch2a
  1312.         inc     di
  1313.         inc     di
  1314.         cmp     di,[bp-2]       ; out of space in text buffer?
  1315.         jnz     ch1a
  1316.         call    write_hc        ; clean it out.
  1317.  
  1318. ch1a:
  1319.         mov     ax,0a0dh        ; crlf
  1320.         mov     es:[di],ax
  1321.         mov     ah,0
  1322.  
  1323. ch2a:
  1324.         inc     si
  1325.         inc     di
  1326.         inc     di
  1327.         cmp     di,[bp-2]       ; this buffer is an even number so
  1328.         jnz     ch3             ; we don't need to worry about
  1329.         push    ax              ; odd addresses like in hex->com
  1330.         call    write_hc        ; [bp-2] = always text buffer
  1331.         pop     ax              ; [bp-4] = always com buffer
  1332.  
  1333. ch3:
  1334.         loop    chloop
  1335.  
  1336.         cmp     byte ptr cs:all_read,TRUE  ; if its all read in
  1337.         jz      ch4                        ; we are almost done.
  1338.         push    ax
  1339.         call    chread          ; else read next and continue
  1340.         pop     ax              ; chread will set CX to length of data
  1341.         cmp     cx,0            ; tried to read past EOF?
  1342.         jz      ch4             ; then we're finished with loop.
  1343.         jmp     chloop
  1344.  
  1345. ch4:
  1346.         push    ax
  1347.         call    write_hc        ; clear buffer to make life simpler
  1348.         pop     ax
  1349.         cmp     ah,0            ; just did EOL?
  1350.         jz      ch4a
  1351.         mov     ax,0a0dh        ; skip extra crlf
  1352.         mov     es:[di],ax
  1353.         inc     di
  1354.         inc     di
  1355.  
  1356. ch4a:
  1357.         mov     ax,0a0dh
  1358.         mov     es:[di],ax
  1359.         inc     di
  1360.         inc     di
  1361.  
  1362.         push    cs              ; write out ;checksum
  1363.         pop     ds
  1364.         mov     si,offset cs:lchksum
  1365.         mov     cx,10
  1366.         cld
  1367.  
  1368.         rep     movsb           ; ;checksum
  1369.  
  1370.         mov     ax,bx           ; compute ASCII representation of
  1371.         mov     dx,0            ; checksum and make it neat.
  1372.         mov     cx,1000
  1373.         div     cx
  1374.         mov     ch,0
  1375.         cmp     ax,0            ; no 1000s?
  1376.         jz      ch5
  1377.         add     al,30h          ; ASCII 0
  1378.         mov     es:[di],al
  1379.         inc     di
  1380.         mov     ch,1
  1381.  
  1382. ch5:
  1383.         mov     ax,dx           ; remainder
  1384.         mov     cl,100
  1385.         div     cl
  1386.         cmp     ch,1
  1387.         jz      ch5a
  1388.         cmp     al,0            ; no 100s?
  1389.         jz      ch6
  1390.  
  1391. ch5a:
  1392.         add     al,30h
  1393.         mov     es:[di],al
  1394.         inc     di
  1395.         mov     ch,1
  1396.  
  1397. ch6:
  1398.         mov     al,ah
  1399.         mov     ah,0
  1400.         mov     cl,10
  1401.         div     cl
  1402.         cmp     ch,1
  1403.         jz      ch6a
  1404.         cmp     al,0            ; no 10s?
  1405.         jz      ch7
  1406.  
  1407. ch6a:
  1408.         add     al,30h
  1409.         mov     es:[di],al
  1410.         inc     di
  1411.  
  1412. ch7:
  1413.         mov     al,ah           ; must print at least one number
  1414.         add     al,30h
  1415.         mov     es:[di],al
  1416.         inc     di
  1417.         mov     ax,0a0dh        ; crlf
  1418.         mov     es:[di],ax
  1419.         inc     di
  1420.         inc     di
  1421.         mov     al,EOF          ; Ctrl-Z
  1422.         mov     es:[di],al
  1423.         inc     di
  1424.  
  1425.         call    write_hc
  1426.         jmp     dhcok1          ; close and finish
  1427.  
  1428.  
  1429. com_hex         endp
  1430.  
  1431. messages        proc    near
  1432.  
  1433. himess  db      '[[hc]]  MS-DOS 2.+ hexconverter,',13,10
  1434.         db      '  v1.4 by Marty Smith.',13,10,13,10,'$'
  1435.  
  1436.  
  1437. need_hex        db      'One of files must be .HEX',13,10,'$'
  1438. not_hex         db      'Not a hex format file.',13,10,'$'
  1439. lchksum         db      ';checksum '   ; 10 bytes
  1440. uchksum         db      ';CHECKSUM '
  1441. msuccess        db      'Successfully created!',13,10,'$'
  1442. chk_ok          db      'Checksum verified.',0
  1443. chk_bad         db      'Checksums different,',13,10
  1444.                 db      'file possibly bad.',0
  1445. chk_no          db      'No checksum found.',0
  1446. disk_full       db      'Disk full.',0
  1447. cancelled       db      'Please check file.',13,10,'$'
  1448. f_len           db      ' bytes recorded.',0
  1449. must_be_20      db      '** Must be running DOS 2.+ **',13,10,'$'
  1450. do_cr           db      13,10,'$'
  1451.  
  1452. ; DOS error returns we may encounter, others return 'unknown error'
  1453.  
  1454. err0    db      'unknown error.',13,10,'$'
  1455. err1    db      'bad function number.',13,10,'$'
  1456. err2    db      'file not found.',13,10,'$'
  1457. err3    db      'path not found.',13,10,'$'
  1458. err4    db      'too many files.',13,10,'$'
  1459. err5    db      'access denied.',13,10,'$'
  1460. err6    db      'invalid handle.',13,10,'$'
  1461. err7    db      'memory blocks damaged.',13,10,'$'
  1462. err8    db      'insufficient memory.',13,10,'$'
  1463. err9    db      'bad memory block address.',13,10,'$'
  1464. err12   db      'bad access code.',13,10,'$'
  1465. err15   db      'bad drive specified.',13,10,'$'
  1466. err17   db      'not same device.',13,10,'$'
  1467. err18   db      'no more files.',13,10,'$'
  1468.  
  1469. error   dw      err0,err1,err2,err3,err4,err5,err6,err7,err8,err9,err0
  1470.         dw      err0,err12,err0,err0,err15,err0,err17,err18
  1471.  
  1472. f_size          dw      0               ; dword file size
  1473.                 dw      0
  1474. txtseg          dw      0               ; memory management
  1475. txtspace        dw      0
  1476. comseg          dw      0
  1477. comspace        dw      0
  1478. space           dw      0               ; temp for figuring workspace
  1479. handle1         dw      0               ; file handles
  1480. handle2         dw      0
  1481. temp            dw      0               ; scratch
  1482. oldstack        dw      0               ; store orig. stack ptr.
  1483.  
  1484. numargs         db      0               ; command line number of args.
  1485. arg1            db      BUFSIZE dup (' ')  ; plenty of space for args
  1486. arg2            db      BUFSIZE dup (' ')  ; and PATHs
  1487. com_to_hex      db      0               ; flags
  1488. check_exe       db      0
  1489. all_read        db      0
  1490.  
  1491. bf_size  db     5 dup (0)               ; bcd file size
  1492.  
  1493. bcd0    db      01h,00h,00h,00h,00h     ; five byte bcd power of 2
  1494.         db      02h,00h,00h,00h,00h     ; 2^0 to 2^24
  1495.         db      04h,00h,00h,00h,00h     ; for showing file size
  1496.         db      08h,00h,00h,00h,00h     ; up to 16meg MS-DOS limit
  1497.         db      16h,00h,00h,00h,00h
  1498.         db      32h,00h,00h,00h,00h
  1499.         db      64h,00h,00h,00h,00h
  1500.         db      28h,01h,00h,00h,00h
  1501.         db      56h,02h,00h,00h,00h
  1502.         db      12h,05h,00h,00h,00h
  1503.         db      24h,10h,00h,00h,00h
  1504.         db      48h,20h,00h,00h,00h
  1505.         db      96h,40h,00h,00h,00h
  1506.         db      92h,81h,00h,00h,00h
  1507.         db      84h,63h,01h,00h,00h
  1508.         db      68h,27h,03h,00h,00h
  1509.         db      36h,55h,06h,00h,00h
  1510.         db      72h,10h,13h,00h,00h
  1511.         db      44h,21h,26h,00h,00h
  1512.         db      88h,42h,52h,00h,00h
  1513.         db      76h,85h,04h,01h,00h
  1514.         db      52h,71h,09h,02h,00h
  1515.         db      04h,43h,19h,04h,00h
  1516.         db      08h,86h,38h,08h,00h
  1517.         db      16h,72h,77h,16h,00h
  1518.  
  1519. ; doc at end so it can be used for stack space.
  1520.  
  1521. doc     db      'Converts HEX format files to COM,EXE or BIN.',13,10
  1522.         db      '  or COM,EXE or BIN files to HEX.',13,10,13,10
  1523.         db      '  Type: >hc in_file [out_file]',13,10,13,10
  1524.         db      'If TWO files are entered, ONE of them MUST be HEX,',13,10
  1525.         db      '  i.e. xxx.HEX xxx.COM = Hex to Com, xxx.EXE xxx.HEX = Exe to Hex.',13,10,13,10
  1526.         db      'If ONE file is entered, the following occurs:',13,10
  1527.         db      '   If the first file has no extension, or it is non-HEX:',13,10
  1528.         db      '       A second file is made in HEX format, with an extension .HEX.',13,10
  1529.         db      '   If the first file has a .HEX extension:',13,10
  1530.         db      '       The program will automatically provide a .COM or .EXE extension,',13,10
  1531.         db      '       depending on file type.'
  1532.         db      '$'
  1533.  
  1534. messages        endp
  1535.  
  1536. cseg    ends                    ; that's all folks
  1537.         end     start
  1538.